package cn.tedu.charging.order.rabbitmq;

import cn.tedu.charging.common.pojo.message.DelayCheckMessage;
import cn.tedu.charging.common.pojo.po.ChargingBillFailPO;
import cn.tedu.charging.common.protocol.WebSocketMessage;
import cn.tedu.charging.order.dao.mapper.ChargingBillFailMapper;
import cn.tedu.charging.order.dao.mapper.ChargingBillSuccessMapper;
import cn.tedu.charging.order.websocket.WebSocketServer;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * 监听 DELAY_BILL_DL_QUEUE
 */
@Component
@Slf4j
public class DelayCheckConsumer {
    @Autowired
    private ChargingBillSuccessMapper chargingBillSuccessMapper;
    @Autowired
    private ChargingBillFailMapper chargingBillFailMapper;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private WebSocketServer webSocketServer;
    @RabbitListener(queues = "DELAY_BILL_DL_QUEUE")
    public void handleGunCheck(DelayCheckMessage message){
        log.debug("当前延迟消息处理开始");
        log.debug("添加抢锁流程,先抢锁 抢到才能执行业务");
        String lockKey="charging:order:"+message.getOrderNo();
        //setnx lockKey "" EX 5属于String数据类型
        Boolean result = redisTemplate.opsForValue().setIfAbsent(lockKey, "", 5, TimeUnit.SECONDS);
        if (!result){
            //说明抢锁失败 别的线程或者消费者正在执行同一个订单的消费逻辑,当前直接结束
            return;
        }
        //1.使用订单编号查询 成功订单 和失败订单
        Boolean exists=checkSuccessOrFail(message.getOrderNo());
        //2.判断是否有订单的记过 exists=true 有 =false没有
        if(!exists){
            //1分钟已经过了,但是订单没有成功或失败的结果--设备自检反馈失败了,认为订单服务继续 创建fail
            //3.创建失败订单 需要用到message所有属性
            createFailBill(message);
            //TODO 4.远程调用生成 优惠券
            //createUserCoupon(message.getUserId());
            //5.通知手机客户端 你赶紧走 送你一张优惠券
            WebSocketMessage<String> webSocketMessage = new WebSocketMessage<>();
            webSocketMessage.setState(1);//1 失败 异常  2 余额不足  3 正常进度同步
            webSocketMessage.setMessage("fail");
            webSocketMessage.setData("B 您的订单创建失败,设备有故障,对不起,送您一张优惠券");
            webSocketServer.pushMessage(message.getUserId(), JSON.toJSONString(webSocketMessage));
        }
    }

    private void createFailBill(DelayCheckMessage message) {
        ChargingBillFailPO po = new ChargingBillFailPO();
        po.setBillId(message.getOrderNo());
        po.setUserId(message.getUserId());
        //operatorId stationId 远程调用device查询
        po.setGunId(message.getGunId());
        po.setVehicleId(message.getVehicleId());
        po.setDeleted(0);
        po.setCreateTime(new Date());
        po.setUpdateTime(new Date());
        po.setFailDesc("设备自检充电失败");
        chargingBillFailMapper.insert(po);
    }

    private Boolean checkSuccessOrFail(String orderNo) {
        //select count() from charging_bill_success where bill_id=#{orderNo}
        //select count() from charging_bill_fail where bill_id=#{orderNo}
        QueryWrapper queryWrapper=new QueryWrapper();
        queryWrapper.eq("bill_id",orderNo);
        Long successCount = chargingBillSuccessMapper.selectCount(queryWrapper);
        Long failCount = chargingBillFailMapper.selectCount(queryWrapper);
        //组织一个表达式 只要有一个数字是>0 反馈就是true
        if (successCount!=null&&failCount!=null){
            return successCount>0||failCount>0;
        }else{
            return false;
        }
    }
}
